package org.gwt.grin.client.commands;

import java.util.Map;

import org.gwt.grin.client.Feature;
import org.gwt.grin.client.Node;
import org.gwt.grin.client.Show;

/**
 * Common base class of all GRIN commands. GRIN defers anything that can change
 * the state of a show to a command.
 * 
 * @author ggeorg
 */
public abstract class Command implements com.google.gwt.user.client.Command,
		Node {

	protected final Show show;

	protected Command(Show show) {
		this.show = show;
	}

	/**
	 * Execute the command. This causes the command to take whatever action it
	 * was created to do. By default, this calls {@link #execute()}.
	 * 
	 * @param caller
	 *            the show that is executed the command; this might not be the
	 *            same as the show this command was created under
	 */
	public void execute(Show show2) {
		execute();
	}

	/**
	 * Return this command, or if needed, a copy of this command.
	 * <p>
	 * Most commands don't have any data members that contain mutable state,
	 * that is, data members whose values are modified (e.g. when the command is
	 * executed). Also, most commands don't refer to part of a scene graph. For
	 * this reason, when a subtree of a scene graph is cloned, most of the
	 * cloned features can just re-use the same {@code Command} objects in their
	 * {@code endCommands arrays}.
	 * <p>
	 * However, some commands contain references to features. If a command in a
	 * subtree being cloned refers to a feature in that subtree, then the cloned
	 * command should refer to the cloned feature. {@code Command}s that do this
	 * should override this method to provide a copy of the command, with the
	 * feature references mapped over.
	 * <p>
	 * Further, it's possible that a {@code Command} might contain a data member
	 * that gets modified, e.g. during command execution. This is probably bad
	 * form, and none of theGRIN commands do this, but if you make a command
	 * subclass that does, you should override this method so that cloned
	 * commands get a new instance of your command subclass.
	 * <p>
	 * The default implementation of this method returns the current instances.
	 * 
	 * @param featureClones
	 *            mapping an original feature of its clone
	 * @return this command, or if needed, a copy of this command
	 */
	public Command cloneIfNeeded(Map<Feature, Feature> featureClones) {
		return this;
	}

	/**
	 * Return a user-friendly string for this command for debugging purposes.
	 * 
	 * @return a user-friendly string for this command
	 */
	public String toString() {
		String nm = getClass().getName();
		int i = nm.lastIndexOf('.');
		if (i >= 0) {
			nm = nm.substring(i + 1, nm.length());
		}
		return nm;
	}
}
